package com.sc.nft.dao;

import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sc.nft.entity.MallDeliveryAddress;
import com.sc.nft.entity.MallOrder;
import com.sc.nft.entity.vo.DistributionOrderVO;
import com.sc.nft.entity.vo.ExportOrderListVO;
import com.sc.nft.entity.vo.mall.AdminMallPageOrderVO;
import com.sc.nft.entity.vo.mall.AdminPageRefundOrderVO;
import com.sc.nft.entity.vo.mall.PageMallOrderVO;
import com.sc.nft.entity.vo.mall.PageMallPopularizeOrderVO;
import com.sc.nft.enums.MallOrderIncomeTypeEnum;
import com.sc.nft.enums.MallOrderRefundStatusEnum;
import com.sc.nft.enums.MallOrderStatusEnum;
import com.sc.nft.enums.SourceEnum;
import com.sc.nft.enums.task.ActivityTypeEnum;
import com.sc.nft.mapper.MallOrderMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * ip商城订单主表(sc_mall_order)数据DAO
 *
 * @author Sun
 * @description 由 Mybatisplus Code Generator 创建
 * @since 2023-05-09 10:46:38
 */
@Slf4j
@Repository
public class MallOrderDao extends ServiceImpl<MallOrderMapper, MallOrder> {

    public List<MallOrder> getListByUserIdAndStatus(Long userId, MallOrderStatusEnum status) {
        LambdaQueryWrapper<MallOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MallOrder::getUserId, userId);
        wrapper.eq(MallOrder::getStatus, status);
        wrapper.eq(MallOrder::getOrderSource, SourceEnum.META_APP);
        return list(wrapper);
    }

    public Integer getListByUserIdAndMallActivityIdAndStatusAndRefundStatus(Long userId, Long mallActivityId) {
        return baseMapper.getListByUserIdAndMallActivityIdAndStatusAndRefundStatus(userId, mallActivityId);
    }

    public Integer getMiniUserBuyCountByUserIdAndActivityId(Long miniUserId, Long mallActivityId) {
        return baseMapper.getMiniUserBuyCountByUserIdAndActivityId(miniUserId, mallActivityId);
    }

    public Page<PageMallOrderVO> pageMallOrder(Long userId, int activityType, Integer queryStatus, Page page, SourceEnum sourceEnum, Long wxMiniUserId) {
        return baseMapper.pageMallOrder(page, userId, activityType, queryStatus, sourceEnum.getCode(), wxMiniUserId);
    }

    public Page<PageMallPopularizeOrderVO> pageMallPopularizeOrder(Long incomeUserId, Integer incomeStatus, Page page) {
        return baseMapper.pageMallPopularizeOrder(page, incomeUserId, incomeStatus);
    }

    public MallOrder getOrderByIdAndUserId(Long id, Long userId, SourceEnum source, Long wxMiniUserId) {
        LambdaQueryWrapper<MallOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MallOrder::getId, id);
        if (SourceEnum.META_APP == source) {
            wrapper.eq(MallOrder::getUserId, userId);
        } else {
            wrapper.eq(MallOrder::getMiniUserId, wxMiniUserId);
        }
        wrapper.eq(MallOrder::getOrderSource, source);
        return getOne(wrapper);
    }

    /**
     * 获取超时订单（无需区分小程序订单还是玛特APP订单）
     *
     * @return
     */
    public List<MallOrder> getTimeOutMallOrder() {
        LambdaQueryWrapper<MallOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MallOrder::getStatus, MallOrderStatusEnum.WAIT_PAY);
        wrapper.lt(MallOrder::getExpiredTime, DateTime.now());
        wrapper.last("limit 200");
        return list(wrapper);
    }

    /**
     * 订单发货（无需区分小程序订单还是玛特APP订单）
     *
     * @param orderId
     * @param status
     * @param deliveryNo
     * @param deliveryName
     * @return
     */
    public boolean updateStatusAndDeliveryNoAndDeliveryNameById(Long orderId, MallOrderStatusEnum status, String deliveryNo, String deliveryName) {
        UpdateWrapper<MallOrder> wrapper = new UpdateWrapper<>();
        wrapper.eq("id", orderId);
        wrapper.eq("status", MallOrderStatusEnum.WAIT_RECEIPT.getCode());
        wrapper.set("status", status.getCode());
        wrapper.set("delivery_no", deliveryNo);
        wrapper.set("delivery_name", deliveryName);
        return update(new MallOrder(), wrapper);
    }

    /**
     * 更新订单状态（无需区分小程序订单还是玛特APP订单）
     *
     * @param id
     * @param status
     * @return
     */
    public Boolean updateStatusById(Long id, MallOrderStatusEnum status) {
        UpdateWrapper<MallOrder> wrapper = new UpdateWrapper<>();
        wrapper.eq("id", id);
        wrapper.set("status", status);
        return update(new MallOrder(), wrapper);
    }

    public List<MallOrder> getAutoConfirmMallOrder(Integer day) {
        return baseMapper.getAutoConfirmMallOrder(day);
    }

    public MallOrder getByOrderNo(String orderNo) {
        LambdaQueryWrapper<MallOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MallOrder::getOrderNo, orderNo);
        return getOne(wrapper);
    }


    public Page<AdminMallPageOrderVO> adminPageOrder(ActivityTypeEnum activityType, String orderNo, Date beginTime, Date endTime, Date payBeginTime, Date payEndTime, String productName, Integer status, Integer payType, Integer isRefund, String userTel, Integer pageNo, Integer pageSize, Long supplierId, String categoryName, SourceEnum orderSource) {
        return baseMapper.adminPageOrder(new Page(pageNo, pageSize), activityType.getCode(), orderNo, beginTime, endTime, payBeginTime, payEndTime, productName, status, payType, isRefund, userTel, supplierId, categoryName, Objects.isNull(orderSource) ? null : orderSource.getCode());
    }

    @Deprecated
    public Page<AdminPageRefundOrderVO> adminPageRefundOrder(String orderNo, String userTel, Integer refundStatus, Integer pageNo, Integer pageSize, Long supplierId) {
        return baseMapper.adminPageRefundOrder(new Page(pageNo, pageSize), orderNo, userTel, refundStatus, supplierId);
    }

    public BigDecimal getUserTotalPrice(Long userId) {
        return baseMapper.getUserTotalPrice(userId);
    }

    public BigDecimal getUserRefundPrice(Long userId) {
        return baseMapper.getUserRefundPrice(userId);
    }

    public Boolean updateIncomeUserId(Long id, Long pushStraightIncomeUserId, Long pushBetweenIncomeUserId, Long cityServerIncomeUserId) {
        UpdateWrapper<MallOrder> wrapper = new UpdateWrapper<>();
        wrapper.eq("id", id);
        wrapper.set("push_straight_income_user_id", pushStraightIncomeUserId);
        wrapper.set("push_between_income_user_id", pushBetweenIncomeUserId);
        wrapper.set("city_server_income_user_id", cityServerIncomeUserId);
        return update(new MallOrder(), wrapper);
    }

    public BigDecimal getByUserIdSum(Long userId, Date beginTime, Date endTime) {
        return baseMapper.getByUserIdSum(userId, beginTime, endTime);
    }

    public MallOrder getByApiOrderNo(String apiOrderNo) {
        return lambdaQuery().eq(MallOrder::getApiOrderNo, apiOrderNo).one();
    }

    public boolean editAdminNoteById(Long id, String adminNote) {
        UpdateWrapper<MallOrder> wrapper = new UpdateWrapper<>();
        wrapper.eq("id", id);
        wrapper.set("admin_note", adminNote);
        return update(new MallOrder(), wrapper);
    }

    public List<ExportOrderListVO> exportOrderList(ActivityTypeEnum type) {
        return baseMapper.exportOrderList(type.getCode());
    }

    public MallOrder byOrderIdAndExpressNumber(String orderId) {
        LambdaQueryWrapper<MallOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MallOrder::getOrderNo, orderId);
        wrapper.eq(MallOrder::getStatus, MallOrderStatusEnum.WAIT_RECEIPT);
        return getOne(wrapper);
    }

    /**
     * 通过售后状态查询售后单
     *
     * @param mallOrderRefundStatusEnum
     * @return
     */
    public List<MallOrder> getByRefundStatus(MallOrderRefundStatusEnum mallOrderRefundStatusEnum) {
        LambdaQueryWrapper<MallOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MallOrder::getRefundStatus, mallOrderRefundStatusEnum);
        return list(wrapper);
    }

    /**
     * 通过订单id查询订单（待支付）微信小程序
     *
     * @param ids
     * @return
     */
    public List<MallOrder> getWxMiniOrderByIds(List<Long> ids, Long wxMiniUserId) {
        LambdaQueryWrapper<MallOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(MallOrder::getId, ids);
        wrapper.eq(MallOrder::getMiniUserId, wxMiniUserId);
        return list(wrapper);
    }

    public Page<DistributionOrderVO> getDistributionOrderVOAdminPage(String orderNO, Date startTime, Date endTime, String miniUserTel, MallOrderStatusEnum orderStatus, MallOrderIncomeTypeEnum incomeStatus, Integer pageNo, Integer pageSize) {
        return baseMapper.getDistributionOrderVOAdminPage(new Page(pageNo, pageSize), orderNO, startTime, endTime, miniUserTel, orderStatus != null ? orderStatus.getCode() : null, incomeStatus != null ? incomeStatus.getCode() : null);
    }

    public boolean updateDeliveryAddress(MallDeliveryAddress mallDeliveryAddress, Long id) {
        LambdaUpdateWrapper<MallOrder> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(MallOrder::getId, id);
        updateWrapper.set(MallOrder::getUserRealName,mallDeliveryAddress.getRecipientName());
        updateWrapper.set(MallOrder::getUserTel,mallDeliveryAddress.getContactNumber());
        updateWrapper.set(MallOrder::getProvince,mallDeliveryAddress.getState());
        updateWrapper.set(MallOrder::getCity,mallDeliveryAddress.getCity());
        updateWrapper.set(MallOrder::getArea,mallDeliveryAddress.getArea());
        updateWrapper.set(MallOrder::getUserAddress,mallDeliveryAddress.getDetailedAddress());
        return update(updateWrapper);
    }
}
